package com.globallogic.training.javase.university.schedule;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import com.globallogic.training.javase.university.curriculum.Activity;
import com.globallogic.training.javase.university.member.Group;

/**
 * Schedule is a table for coordinating four elements: students of a group,
 * instructors, rooms, time slots.
 * 
 * @author Artem.Zeltinsh
 */
public class Schedule {

	private Set<ScheduledActivity> scheduledActivities;

	public Schedule() {
		this.scheduledActivities = new LinkedHashSet<ScheduledActivity>();
	}

	public void scheduleActivity(Activity activity, DayOfWeek dayOfWeek,
			TimeSlot timeSlot, Auditorium auditorium) {

		ScheduledActivity searchedActivity = null;
		for (ScheduledActivity item : scheduledActivities) {
			if (item.getTimeSlot().equals(timeSlot)
					&& item.getDayOfWeek().equals(dayOfWeek)) {
				searchedActivity = item;
				break;
			}
		}

		if (searchedActivity == null) {
			ScheduledActivity schedActivity = new ScheduledActivity();
			schedActivity.setActivity(activity);
			schedActivity.setDayOfWeek(dayOfWeek);
			schedActivity.setTimeSlot(timeSlot);
			schedActivity.setAuditorium(auditorium);
			scheduledActivities.add(schedActivity);
		}
	}

	public void scheduleActivity(Activity activity, Set<Auditorium> auditoriums) {
		for (DayOfWeek dayOfWeek : DayOfWeek.values()) {
			for (TimeSlot timeSlot : TimeSlot.values()) {
				for (Auditorium auditorium : auditoriums) {

					ScheduledActivity sa = new ScheduledActivity();
					sa.setActivity(activity);
					sa.setDayOfWeek(dayOfWeek);
					sa.setTimeSlot(timeSlot);
					sa.setAuditorium(auditorium);
					if (checkGroupsConstraint(sa)
							&& scheduledActivities.add(sa)) {
						return;
					}
				}
			}
		}

		return;
	}

	public ScheduledActivity getScheduledActivity(Group group,
			DayOfWeek dayOfWeek, TimeSlot timeSlot) {
		for (ScheduledActivity activity : scheduledActivities) {
			if (activity.getGroups().contains(group)
					&& activity.getTimeSlot().equals(timeSlot)
					&& activity.getDayOfWeek().equals(dayOfWeek)) {
				return activity;
			}
		}

		return null;
	}

	private List<ScheduledActivity> getScheduledActivity(Set<Group> groups) {
		List<ScheduledActivity> result = new ArrayList<ScheduledActivity>();
		for (ScheduledActivity activity : scheduledActivities) {
			for (Group group : groups) {
				if (activity.getActivity().getEnrolledGroups().contains(group)) {
					result.add(activity);
				}
			}
		}

		return result;
	}

	private boolean checkGroupsConstraint(ScheduledActivity activity) {
		List<ScheduledActivity> scheduledActivities = getScheduledActivity(activity
				.getGroups());
		for (ScheduledActivity nActivity : scheduledActivities) {
			if (nActivity.getDayOfWeek().equals(activity.getDayOfWeek())
					&& nActivity.getTimeSlot().equals(activity.getTimeSlot())) {
				return false;
			}
		}

		return true;
	}

	public Set<Group> getGroups() {
		Set<Group> groups = new LinkedHashSet<Group>();
		for (ScheduledActivity activity : scheduledActivities) {
			groups.addAll(activity.getGroups());
		}
		return groups;
	}

	@Override
	public String toString() {
		return scheduledActivities.toString();
	}
}
